package craky.keeper.client;

import java.sql.Date;
import java.sql.Timestamp;
import java.util.Calendar;

import android.app.Activity;
import android.app.FragmentManager;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.text.InputType;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import craky.keeper.bean.Income;
import craky.keeper.bean.KeeperObject;
import craky.keeper.bean.Pay;
import craky.keeper.bean.ResultSet;
import craky.keeper.client.task.KeeperTask;
import craky.keeper.util.KeeperUtil;
import craky.keeper.view.DetailItemText;
import craky.keeper.view.GlassView;
import craky.keeper.view.ToastView;

public class DetailActivity extends Activity
{
    private LinearLayout itemParent;

    private ToastView toast;

    private GlassView glass;

    private LinearLayout itemDate, itemAmount, itemType, itemSummary, itemRecorder, itemRecordTime, itemDetail, itemRemark;

    private InputMethodManager imManager;

    private Resources resources;

    private KeeperObject keeperData;

    private KeeperTask keeperTask;

    private boolean isPay, softInputVisible;

    private String action;

    private long lastBackPressedTime;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);
        Intent intent = this.getIntent();
        this.keeperData = (KeeperObject)intent.getSerializableExtra(KeeperUtil.KEY_KEEPER_DATA);
        this.isPay = intent.getBooleanExtra(KeeperUtil.KEY_IS_PAY, true);
        this.action = intent.getStringExtra(KeeperUtil.KEY_ACTION);
        this.itemParent = (LinearLayout)findViewById(R.id.itemParent);
        this.toast = (ToastView)findViewById(R.id.toast);
        this.glass = (GlassView)findViewById(R.id.glass);
        this.resources = this.getResources();
        this.imManager = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
        findViewById(R.id.rootView).addOnLayoutChangeListener(new View.OnLayoutChangeListener()
        {
            public void onLayoutChange(View view, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)
            {
                softInputVisible = oldBottom - bottom > 100 * KeeperUtil.density;
            }
        });
        resetHeader();
        resetItems();
    }

    private void resetHeader()
    {
        TextView txtTitle = (TextView)findViewById(R.id.txtTitle);
        boolean showRightButton = true;

        switch(action)
        {
            case KeeperUtil.ACTION_ADD:
            {
                txtTitle.setText(resources.getString(isPay? R.string.add_pay: R.string.add_income));
                break;
            }
            case KeeperUtil.ACTION_MODIFY:
            {
                txtTitle.setText(resources.getString(isPay? R.string.modify_pay: R.string.modify_income));
                break;
            }
            case KeeperUtil.ACTION_SHOW_DETAIL:
            {
                showRightButton = false;
                txtTitle.setText(resources.getString(isPay? R.string.show_pay: R.string.show_income));
                break;
            }
        }

        if(showRightButton)
        {
            Button rightButton = (Button)findViewById(R.id.btnTitleRight);
            rightButton.setText(resources.getString(R.string.finish));
            rightButton.setVisibility(View.VISIBLE);
        }

        ((Button)findViewById(R.id.btnTitleLeft)).setVisibility(View.VISIBLE);
        txtTitle.setVisibility(View.VISIBLE);
    }

    private void resetItems()
    {
        int dateLabelID = isPay? R.string.pay_date: R.string.income_date;
        int[] labelIDs = {dateLabelID, R.string.amount, R.string.summary, R.string.type, R.string.record_time, R.string.recorder, R.string.detail,
                        R.string.remark};
        String[] itemValues = null;
        boolean isShow = action.equals(KeeperUtil.ACTION_SHOW_DETAIL);
        int count = itemParent.getChildCount();
        int labelIndex = 0;
        itemRecordTime = (LinearLayout)findViewById(R.id.itemRecordTime);
        itemRecorder = (LinearLayout)findViewById(R.id.itemRecorder);
        itemDate = (LinearLayout)findViewById(R.id.itemDate);
        itemType = (LinearLayout)findViewById(R.id.itemType);
        itemDetail = (LinearLayout)findViewById(R.id.itemDetail);
        itemRemark = (LinearLayout)findViewById(R.id.itemRemark);
        LinearLayout[] readonlyItems = {itemRecordTime, itemRecorder, itemDate, itemType};
        View view;
        LinearLayout item;
        DetailItemText itemText;
        ((DetailItemText)itemDetail.getChildAt(1)).setMultiLine();
        ((DetailItemText)itemRemark.getChildAt(1)).setMultiLine();

        if(keeperData != null)
        {
            itemValues = new String[]{KeeperUtil.DATE_FORMAT.format(keeperData.getDate()), keeperData.getAmountString().replaceAll(",", ""),
                            keeperData.getSummary(), keeperData.getType(), keeperData.getRecordTime().toString(), keeperData.getRecorder(),
                            keeperData.getDetail(), keeperData.getRemark()};
        }

        for(int i = 0; i < count; i++)
        {
            view = itemParent.getChildAt(i);

            if(view instanceof LinearLayout)
            {
                item = (LinearLayout)view;
                itemText = (DetailItemText)item.getChildAt(1);
                ((TextView)item.getChildAt(0)).setText(resources.getString(labelIDs[labelIndex]));

                if(itemValues != null)
                {
                    itemText.setText(itemValues[labelIndex]);
                }

                if(isShow)
                {
                    itemText.setReadonly();
                }

                labelIndex++;
            }
        }

        if(!isShow)
        {
            itemAmount = (LinearLayout)findViewById(R.id.itemAmount);
            itemSummary = (LinearLayout)findViewById(R.id.itemSummary);
            ((DetailItemText)itemAmount.getChildAt(1)).setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
            itemDate.getChildAt(1).setOnTouchListener(new ChooserListener(R.string.choose_date));
            itemType.getChildAt(1).setOnTouchListener(new ChooserListener(R.string.choose_type));
            itemRecordTime.setVisibility(View.GONE);
            itemRecorder.setVisibility(View.GONE);

            for(LinearLayout readonlyItem: readonlyItems)
            {
                ((DetailItemText)readonlyItem.getChildAt(1)).setReadonly();
            }

            if(action.equals(KeeperUtil.ACTION_ADD))
            {
                String date = KeeperUtil.DATE_FORMAT.format(Calendar.getInstance().getTime());
                ((DetailItemText)itemDate.getChildAt(1)).setText(date);
            }
        }
    }

    @Override
    protected void onPause()
    {
        itemParent.requestFocus();
        super.onPause();
    }

    @Override
    public void onBackPressed()
    {
        if(glass.getVisibility() == View.VISIBLE)
        {
            long current = System.currentTimeMillis();

            if(current - lastBackPressedTime > 2000)
            {
                lastBackPressedTime = current;
                Toast.makeText(this, R.string.press_again_cancel, Toast.LENGTH_SHORT).show();
            }
            else
            {
                if(keeperTask != null)
                {
                    keeperTask.cancel(false);
                    keeperTask = null;
                }

                super.onBackPressed();
            }
        }
        else
        {
            super.onBackPressed();
        }
    }

    public void onBackClick(View view)
    {
        this.onBackPressed();
    }

    public void clearInputType()
    {
        itemType.post(new Runnable()
        {
            public void run()
            {
                ((DetailItemText)itemType.getChildAt(1)).setText("");
            }
        });
    }

    private String getInputValue(LinearLayout item)
    {
        return ((DetailItemText)item.getChildAt(1)).getText().toString();
    }

    private boolean validateInput()
    {
        boolean pass = true;
        LinearLayout[] items = {itemAmount, itemSummary, itemType};
        int[] infoIDs = {R.string.amount_can_not_empty, R.string.summary_can_not_empty, R.string.type_can_not_empty};
        int count = items.length;

        for(int i = 0; i < count; i++)
        {
            if(getInputValue(items[i]).length() == 0)
            {
                toast.showToast(R.drawable.toast_icon_w, resources.getString(infoIDs[i]));
                pass = false;
                break;
            }
        }

        if(pass)
        {
            float amount = Float.parseFloat(String.format("%.2f", Float.parseFloat(getInputValue(itemAmount))));

            if(amount <= 0)
            {
                pass = false;
                toast.showToast(R.drawable.toast_icon_w, resources.getString(R.string.amount_must_greater_than_0));
            }
        }

        return pass;
    }

    private void submit()
    {
        itemParent.requestFocus();
        imManager.hideSoftInputFromWindow(itemParent.getWindowToken(), 0);
        glass.setVisibility(View.VISIBLE);
        toast.startTask(R.drawable.loading, resources.getString(R.string.operating));
        KeeperObject tempData = isPay? new Pay(): new Income();
        boolean isAdd = action.equals(KeeperUtil.ACTION_ADD);

        if(isAdd)
        {
            tempData.setRecorder(KeeperUtil.currentUser.getName());
            tempData.setRecordTime(new Timestamp(System.currentTimeMillis()));
        }
        else
        {
            tempData.setId(keeperData.getId());
            tempData.setRecorder(keeperData.getRecorder());
            tempData.setRecordTime(keeperData.getRecordTime());
        }

        try
        {
            tempData.setDate(new Date(KeeperUtil.DATE_FORMAT.parse(getInputValue(itemDate)).getTime()));
            tempData.setAmountString(String.format("%.2f", Float.parseFloat(getInputValue(itemAmount))));
            tempData.setSummary(getInputValue(itemSummary));
            tempData.setType(getInputValue(itemType));
            tempData.setDetail(getInputValue(itemDetail));
            tempData.setRemark(getInputValue(itemRemark));
            keeperTask = new KeeperTask(this, keeperData, tempData, action);
            keeperTask.execute(isPay, isAdd);
        }
        catch(Exception e)
        {}
    }

    public void dealOperationResult(KeeperTask task, String errorMessage, ResultSet resultSet)
    {
        if(this.keeperTask != task)
        {
            return;
        }

        if(errorMessage != null)
        {
            toast.stopTask();
            glass.setVisibility(View.GONE);
            toast.showToast(R.drawable.toast_icon_w, errorMessage);
        }
        else if(resultSet != null)
        {
            Intent intent = new Intent();
            intent.putExtra(KeeperUtil.KEY_IS_PAY, isPay);
            intent.putExtra(KeeperUtil.KEY_KEEPER_DATA, resultSet);
            setResult(KeeperUtil.RESULT_CODE_OK, intent);
            this.finish();
        }

        this.keeperTask = null;
    }

    public void onTitleRightClick(View view)
    {
        if(validateInput())
        {
            submit();
        }
    }

    private class ChooserListener implements View.OnTouchListener
    {
        private ChooserDialog dialog;

        private int titleId;

        private boolean needDelay;

        public ChooserListener(int titleId)
        {
            this.titleId = titleId;
        }

        private void showChooser(View view)
        {
            DetailActivity activity = DetailActivity.this;
            String title = resources.getString(titleId);
            String[] chooserItems;

            if(titleId == R.string.choose_date)
            {
                chooserItems = KeeperUtil.getDateArrays(90);
            }
            else
            {
                chooserItems = KeeperUtil.getCategoryNames(isPay);
            }

            if(dialog == null)
            {
                dialog = new ChooserDialog(activity, chooserItems, title, (EditText)view);
            }
            else
            {
                dialog.reset(chooserItems, title, (EditText)view);
            }

            FragmentManager fm = activity.getFragmentManager();
            dialog.show(fm, null);
        }

        @Override
        public boolean onTouch(final View view, MotionEvent event)
        {
            int action = event.getAction();

            if(action == MotionEvent.ACTION_DOWN && softInputVisible)
            {
                needDelay = true;
                view.requestFocus();
                imManager.hideSoftInputFromWindow(itemParent.getWindowToken(), 0);
            }
            else if(action == MotionEvent.ACTION_UP)
            {
                if(needDelay)
                {
                    needDelay = false;
                    itemParent.postDelayed(new Runnable()
                    {
                        public void run()
                        {
                            showChooser(view);
                        }
                    }, 200L);
                }
                else
                {
                    showChooser(view);
                }
            }

            return false;
        }
    }
}